<?php

namespace youmbe\rbac\controllers;

use Yii;
use common\rest\Controller;
use youmbe\rbac\models\Assignment;
use youmbe\rbac\models\searchs\AssignmentSearch;
use yii\web\NotFoundHttpException;
use yii\helpers\ArrayHelper;
use youmbe\rbac\models\User;

/**
 * AssignmentController implements the CRUD actions for Assignment model.
 *
 * @author Misbahul D Munir <misbahuldmunir@gmail.com>
 * @since 1.0
 */
class AssignmentController extends Controller {

    public $userClassName;
    public $idField = 'id';
    public $usernameField = 'username';
    public $fullnameField;
    public $searchClass;
    public $extraColumns = [];

    /**
     * @inheritdoc
     */
    public function init() {
        parent::init();
        if ($this->userClassName === null) {
            $this->userClassName = Yii::$app->getUser()->identityClass ?: User::class;
        }
    }

    /**
     * @inheritdoc
     */
    protected function verbs() {
        return ArrayHelper::merge(parent::verbs(), [
            'assign' => ['post'],
            'revoke' => ['post'],
        ]);
    }

    /**
     * Lists all Assignment models.
     * @return mixed
     */
    public function actionIndex() {
        if ($this->searchClass === null) {
            $searchModel = new AssignmentSearch;
            $searchModel->modelClass = $this->userClassName;
            $dataProvider = $searchModel->search(Yii::$app->getRequest()->getQueryParams(), $this->usernameField);
        } else {
            $class = $this->searchClass;
            $searchModel = new $class;
            $dataProvider = $searchModel->search(Yii::$app->getRequest()->getQueryParams());
        }
        return $dataProvider;
    }

    /**
     * Displays a single Assignment model.
     * @param  integer $id
     * @return mixed
     */
    public function actionView($id) {
        $model = $this->findModel($id);
        return [
            'model' => $model,
            'items' => $model->getItems(),
        ];
    }

    /**
     * Assign items
     * @param string $id
     * @return array
     */
    public function actionAssign2($id) {
        $items = Yii::$app->getRequest()->post('items', []);
        $model = $this->findModel($id);
        $assigned = $model->getAssignments();

        $revokes = [];
        $assigns = [];
        foreach ($assigned as $assign) {
            if (in_array($assign, $items)) {
                continue;
            } else {
                $revokes[] = $assign;
            }
        }
        foreach ($items as $item) {
            if (in_array($item, $assigned)) {
                continue;
            } else {
                $assigns[] = $item;
            }
        }
        $data = [];
        if (!empty($revokes)) {
            $data['revoke'] = $model->revoke($revokes);
        }
        if (!empty($assigns)) {
            $data['assign'] = $model->assign($assigns);
        }
        return $data;
    }

    /**
     * Assign items
     * @param string $id
     * @return array
     */
    public function actionAssign($id) {
        $items = Yii::$app->getRequest()->post('items', []);
        $model = $this->findModel($id);

        $assigned = $model->getAssignments();
        $revokes = [];
        $assigns = [];
        foreach ($assigned as $assign) {
            ArrayHelper::removeValue($items, $assign);
        }
        foreach ($items as $item) {
            if (in_array($item, $assigned)) {
                continue;
            } else {
                $assigns[] = $item;
            }
        }
        $data = [];
        if (!empty($revokes)) {
            $data['revoke'] = $model->revoke($revokes);
        }
        if (!empty($assigns)) {
            $data['assign'] = $model->assign($assigns);
        }
        return $model->getItems();
    }

    /**
     * Assign items
     * @param string $id
     * @return array
     */
    public function actionRevoke($id) {
        $items = Yii::$app->getRequest()->post('items', []);
        $model = new Assignment($id);
        $success = $model->revoke($items);
        if (!$success) {
            parent::error('取消授权失败');
        }
        return $model->getItems();
    }

    /**
     * Finds the Assignment model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param  integer $id
     * @return Assignment the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id) {
        $class = $this->userClassName;
        $user = $class::findIdentity($id);
        if ($user !== null) {
            return new Assignment($id, $user);
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }

}
